package infoserver;

import java.net.ServerSocket;
import java.net.Socket;
import java.io.IOException;

/**
 * Dit is de klasse waar het server geraamte zich bevindt. 
 * Vanhieruit word de socket gestart en begint de server met luisteren naar mogelijke clients.
 * @author Michael Stevens
 * @since 03-05-2012
 */

public class InfoServerSocket implements Runnable{

    private int serverPort = 5555;
    private ServerSocket serverSocket = null;
    private Socket clientSocket;
    private boolean isStopped = false, running = false;
    private Thread runningThread = null;
    private Infoserver is;
    public int connections = 0;

    public InfoServerSocket(Infoserver is){
        this.is = is;
    }
    
    /**
    * Omdat deze class Runnable implementeert moet deze de methode run overschijven.
    * Dit is wat de server moet uitvoeren om te starten.
    * Binnen de while loop wordt geluisterd naar mogelijke verbindingen
    * Als een client connect wordt er een nieuwe thread gemaakt om deze af the handelen
    * @author Michael Stevens
    * @since 03-05-2011
    */
    public void run(){
        this.running = true;
        synchronized(this){
            this.runningThread = Thread.currentThread();
        }
        openServerSocket();
        while(! isStopped()){
            //Socket clientSocket = null;
            try {
                clientSocket = this.serverSocket.accept();
            } catch (IOException e) {
                if(isStopped()) {
                     is.getGui().writeLog("Server gestopt");
                    return;
                }
                is.getGui().writeLog("Error bij het accepteren van de client " + e.getMessage());                       
            }
            new Thread(new InfoServerThread(clientSocket, is)).start();
        }
        is.getGui().writeLog("Server gestopt");
        this.running = false;
    }

    /**
     * @return the stopped
     */
    public synchronized boolean isStopped() {
        return this.isStopped;
    }
    
    /**
     * @return set the stopped
     */
    public synchronized void setStopped(boolean f){
        this.isStopped = f;
    }
    
    /**
    * Stopt de server
    * @author Michael Stevens
    * @since 03-05-2011
    */
    public synchronized void stop(){
        this.isStopped = true;
        this.running = false;        
        try {
            this.serverSocket.close();            
            if(clientSocket != null){ // kijk of client socket aangemaakt is om nullpointer te voorkomen bij het stoppen van -s
                                      //de server zonder eerder gemaakte connecties
                this.clientSocket.close();  // zoja sluit deze
            }            
        } catch (IOException e) {
            is.getGui().writeLog("Fout bij het sluiten van de server " + e.getMessage());            
        }
    }
    
    /**
    * Opent de serversocket om op te luisteren op de ingestelde poort
    * @author Michael Stevens
    * @since 03-05-2011
    */
    public void openServerSocket() {
        try {
            this.serverSocket = new ServerSocket(this.serverPort);
            is.getGui().writeLog("Server gestart op poort : " + serverPort);
        } catch (IOException e) {
            is.getGui().writeLog("Kan de server niet starten " + e.getMessage());   
        }
    }

    /**
     * @return the running
     */
    public synchronized boolean isRunning() {
        return running;
    }

}